/*
 * Copyright (c) 2012 Jonathan Tyers
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.org.uplink.configproxy;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.apache.commons.configuration.HierarchicalConfiguration;

/**
 * For a class annotated with {@code @}{@link ConfigProxy}, maps a method to a key in an {@link HierarchicalConfiguration Apache Commons
 * configuration}.
 * <p>
 * Values coming out of the configuration will perform conversion as needed to return values of the correct type. Return types must be one of:
 * <ul>
 * <li>BigDecimal</li>
 * <li>BigInteger</li>
 * <li>Boolean</li>
 * <li>Double</li>
 * <li>Float</li>
 * <li>Integer</li>
 * <li>Long</li>
 * <li>Short</li>
 * <li>String</li>
 * <li>List</li>
 * </ul>
 * 
 * @author jonny
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConfigValue {

	/**
	 * The name of the configuration key this configuration value maps to. This will be relative to the <tt>basekey</tt> in the enclosing class
	 * {@link ConfigProxy} annotation, if set.
	 */
	String key();

	/**
	 * If defaultKey is specified, the value for that key will be used if the key for this configuration value has no value.
	 */
	String defaultKey() default "";

	/**
	 * If defaultValue is specified, that value will be used if the key for this configuration value has no value. (The default value will undergo
	 * conversion and validation as normal.)
	 */
	String defaultValue() default "";

	/**
	 * A regular expression that can be used to validate the value of this setting (for non-strings, the toString() of the value is used to validate).
	 * If, when this method is called the value returned does not match this regular expression, an exception is thrown. For lists, each individual
	 * item in the list is validated separately.
	 */
	String pattern() default Patterns.ANYTHING;

	/**
	 * Additional flags.
	 */
	Option[] options() default {};

    /**
     * If true, then key specified is treated as the "absolute" value passed to the configuration when looking up
     * values.  Therefore, it is *not* combined with the @ConfigProxy basekey value.  If no @ConfigProxy basekey
     * value is specified, then absolute has no meaning, the behavior is the same
     */
    boolean absolute() default false;

    /**
     * If true, then the defaultKey specified is treated as the "absolute" value passed to the configuration when
     * looking up values.  Therefore, it is *not* combined with the @ConfigProxy basekey value. If no @ConfigProxy
     * basekey value is specified, then absolute has no meaning, the behavior is the same
     */
    boolean defaultKeyAbsolute() default false;
}
